package cn.autumnorange.app.common.provider.rpc.lock.aop;

import cn.autumnorange.app.common.consumerproducer.util.AnnotationUtil;
import cn.autumnorange.app.common.provider.rpc.ProviderRPCService;
import org.aopalliance.aop.Advice;
import org.redisson.api.RedissonClient;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RestController;

import java.lang.annotation.Annotation;

@Component
public class RPCLockKeyAdvisor extends AbstractPointcutAdvisor {
  //  @Autowired private RedisLockRegistry redisLockRegistry;

  @Autowired private ApplicationContext applicationContext;
  private volatile RPCKeyLockMethodInterceptor rpcKeyLockMethodInterceptor = null;
  @Autowired private ProviderRPCService providerRPCService;

  @Value("${ribbon.ConnectTimeout}")
  private long connectTimeout;

  @Value("${ribbon.ReadTimeout}")
  private long readTimeout;

//  @Value("${ribbon.MaxAutoRetries}")
//  private int maxAutoRetries;
//
//  @Value("${ribbon.MaxAutoRetriesNextServer}")
//  private int maxAutoRetriesNextServer;

  // spring ApplicationContext 全局实例上下文会自动注入
  public RPCLockKeyAdvisor() {}

  @Override
  public Pointcut getPointcut() {
    return new Pointcut() {
      @Override
      public ClassFilter getClassFilter() {
        return (Class<?> clazz) ->
                AnnotationUtil.existsAnnotation(clazz, org.springframework.stereotype.Controller.class)
                || AnnotationUtil.existsAnnotation(clazz, RestController.class);
      }

      @Override
      public MethodMatcher getMethodMatcher() {
        return MethodMatcher.TRUE;
      }
    };
  }

  @Override
  public Advice getAdvice() {
    if (rpcKeyLockMethodInterceptor == null) {
      synchronized (RPCKeyLockMethodInterceptor.class) {
        if (rpcKeyLockMethodInterceptor == null) {
          rpcKeyLockMethodInterceptor =
              new RPCKeyLockMethodInterceptor(
                  applicationContext.getBean(RedissonClient.class),
                      providerRPCService,
                  connectTimeout,
                  readTimeout);
        }
      }
    }
    return rpcKeyLockMethodInterceptor;
  }


}
